﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XingLucifer.Devices.Models;
using XingLucifer.IBase;

namespace XingLucifer.Devices.Devices.Testers
{
    public class RJ6901A : IDevices
    {
        private ICommunication _com;
        private CancellationTokenSource _tokenSource;
        public RJ6901A(ICommunication com, CancellationTokenSource tokenSource)
        {
            _com = com;
            _tokenSource = tokenSource;
        }

        public bool WriteClass<TClass>(TClass value, int address, int count = 3) where TClass : class
        {
            throw new NotImplementedException("未实现");
        }
        private byte[] _quyData = new byte[] { 0x7B, 0x00, 0x08, 0x02, 0xF0, 0x11, 0x0B, 0x7D };//查询测试数据
        //private byte[] _rJ6902CAGX_quyData = new byte[] { 0x7B, 0x00, 0x08, 0x02, 0xF0, 0x5B, 0x55, 0x7D };//查询测试数据

        public TClass ReadClass<TClass>(int address, TClass obj = null, int count = 3) where TClass : class
        {
            byte[] bytes = null;
            for (int i = 0; i < count; i++)
            {
                try
                {
                    Thread.Sleep(100);
                    //_com.Write(address == 0 ? _quyData : _rJ6902CAGX_quyData);
                    _com.Write(_quyData);
                    bytes = _com.Read(1024);


                    if (bytes.Length < 9)
                    {
                        throw new Exception("协议通信无响应");
                    }else if (bytes[18] ==02)   //2状态测试中，重新取值
                    {
                        continue;
                    }
                    //return address == 0 ? ToResult__RJ6902R(bytes) as TClass : ToResult_RJ6902CAGX(bytes) as TClass;
                    return ToResult__RJ6901A(bytes) as TClass;
                }
                catch (Exception)
                {
                    if (_tokenSource.Token.IsCancellationRequested)
                    {
                        return default;
                    }
                    _com.ReconnectDisconnection?.Invoke(_com, _com.Index, _com.IP, _com.Port, _com.DeviceType, _com.TaskType, _com.ServiceName, _tokenSource);
                }
            }
            return default;
        }
        private RJ6901AResultModel ToResult__RJ6901A(byte[] bytes)
        {
            if (bytes == null) { return null; }
            if (bytes.Length < 22) { return null; }
            return new RJ6901AResultModel()
            {
                电压 = ToUShort(bytes.Skip(6).ToArray()),
                电阻 = ToInt(bytes.Skip(8).ToArray()) / 1000.0F,
                电流 = ToInt(bytes.Skip(12).ToArray()) / 1000.0F,
                测试耗时时间 = (ToUShort(bytes.Skip(16).ToArray()))/10,
                总结果 = bytes[19],
                TestMsg = BitConverter.ToString(bytes)
            };
        }

        private int ToInt(byte[] bytes) => (int)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
        private ushort ToUShort(byte[] bytes) => (ushort)((bytes[0] << 8) | bytes[1]);
        public Task Read()
        {
            throw new NotImplementedException("未实现");
        }

        public bool WriteSingle(object value, int address, int offset, int length, int count = 3)
        {
            byte[] bytes = (byte[])value;
            for (int i = 0; i < count; i++)
            {
                try
                {
                    _com.Write(bytes);
                    return true;
                }
                catch (Exception)
                {
                    if (_tokenSource.Token.IsCancellationRequested)
                    {
                        return false;
                    }
                    _com.ReconnectDisconnection?.Invoke(_com, _com.Index, _com.IP, _com.Port, _com.DeviceType, _com.TaskType, _com.ServiceName, _tokenSource);
                }
            }
            return false;
        }

        public TValue? ReadSingle<TValue>(int address, int length, int count = 3)
        {
            byte[] bytes = default;
            for (int i = 0; i < count; i++)
            {
                try
                {
                    bytes = _com.Read(length);
                    return bytes == null ? default : (TValue)(object)bytes;
                }
                catch (Exception)
                {
                    if (_tokenSource.Token.IsCancellationRequested)
                    {
                        return default;
                    }
                    _com.ReconnectDisconnection?.Invoke(_com, _com.Index, _com.IP, _com.Port, _com.DeviceType, _com.TaskType, _com.ServiceName, _tokenSource);
                }
            }
            return default;
        }

        public bool Open() => _com.Open();

        public void Close() => _com.Close();
    }
}
